/**
 * author      : dormi330
 * date        : 2018/6/27
 * project     : mybatis
 * description : 支付一个已经存在的订单
 */

package com.deep.trade.domain.cart;

import com.deep.trade.adaptor.required.IdService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.deep.trade.adaptor.required.DistributeLockService;
import com.deep.trade.adaptor.required.sku.Sku;
import com.deep.trade.common.TradeException;

@Service
public class CommandOfCart {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());
    private static final int ONLY_ONE_SHOULD_BE_UPDATED = 1;

    @Autowired
    private CartQueryRepository cartQueryRepository;

    @Autowired
    private CartRepository cartRepository;

    @Autowired
    private IdService idService;


    @Autowired
    private DistributeLockService distributeLockService;

    @Transactional
    public void addSkuToCart(String tenantCode, String memberId, Sku sku, int quantity) throws Exception {

        if (quantity <= 0) {
            throw new TradeException("cannot get distribute lock for add cartSku to sku");
        }

        // 如果购物车已经有了, 则修改数量
        String skuId = sku.getSkuCode();
        CartSku oldCartSku = cartQueryRepository.cartOfSpecificMemberAndSku(tenantCode, memberId, skuId);

        if (null != oldCartSku) {
            oldCartSku.setQuantity(oldCartSku.getQuantity() + quantity);
            cartRepository.cartSkuQuantityChanged(oldCartSku);
            return;
        }

        CartSku cartSku = new CartSku();
        cartSku.setId(idService.uuid());
        // tenantCode memberId skuId quantity
        cartSku.setTenantCode(tenantCode);
        cartSku.setMemberId(memberId);
        cartSku.setQuantity(quantity);
        // seller , sku
        cartSku.setSellerId(sku.getSellerId());
        cartSku.setShopId(sku.getShopId());
        cartSku.setItemId(sku.getItemId());
        cartSku.setItemName(sku.getItemName());
        cartSku.setSkuId(sku.getId());
        cartSku.setSkuCode(sku.getSkuCode());

        cartSku.setSkuVersion(sku.getVersion());
        cartSku.setPriceMoney(sku.getPrice());

        // 防止添加多条记录
        boolean hasLock = distributeLockService.getLock();
        if (!hasLock) {
            throw new TradeException("cannot get distribute lock for add cartSku to sku");
        }

        try {
            int count = cartRepository.skuAddToCart(cartSku);
            if (count != ONLY_ONE_SHOULD_BE_UPDATED) {
                throw new TradeException("add to cart fail");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        } finally {
            distributeLockService.releaseLock();
        }
    }

    // 从购物车中移除
    @Transactional
    public void removeSkuFromCart(String tenantCode, String memberId, String skuId) throws Exception {
        CartSku cartSku = cartQueryRepository.cartOfSpecificMemberAndSku(tenantCode, memberId, skuId);
        if (null == cartSku) throw new TradeException("no such sku in cart");

        try {
            int count = cartRepository.removeCartSku(cartSku);
            if (count != ONLY_ONE_SHOULD_BE_UPDATED) {
                throw new TradeException("remove cart item fail");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }

    }

    @Transactional
    public void alterQuantity(String tenantCode, String memberId, String skuId, int lastQuantity) throws Exception {
        CartSku cartSku = cartQueryRepository.cartOfSpecificMemberAndSku(tenantCode, memberId, skuId);
        if (null == cartSku) throw new TradeException("no such sku in cart");

        cartSku.setQuantity(lastQuantity);

        try {
            int count = cartRepository.cartSkuQuantityChanged(cartSku);
            if (count != ONLY_ONE_SHOULD_BE_UPDATED) {
                throw new TradeException("alter quantity fail");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }
    }

    private CartSku findCart(String tenantCode, String memberId, String skuId) {
        return cartQueryRepository.cartOfSpecificMemberAndSku(tenantCode, memberId, skuId);
    }
}